﻿using Rw.Core.Common.Paging;
using WH.Common.Bases.IBase;
using WH.Common.Helper;
using WH.Common.Paging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace WH.Common.Paging
{
    public static class PaginationOrderByExtensions
    {


        /// <summary>
        /// 自定义字段排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="propertyName"></param>
        /// <param name="isAscending"></param>
        /// <returns></returns>
        public static IEnumerable<T> SortListByPropertyName<T>(this IEnumerable<T> list, string? propertyName, bool isAscending)
        {
            if (string.IsNullOrWhiteSpace(propertyName))
            {
                if (typeof(T).GetProperty(nameof(IAuditable.CreatedTime)) is not null)
                {
                    propertyName = nameof(IAuditable.CreatedTime);
                }
            }

            PropertyInfo? propInfo = typeof(T).GetProperties()
                                              .FirstOrDefault(p => p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase));

            if (propInfo is null)
            {
                return list;
            }

            // 创建比较逻辑
            Comparison<T> comparison = CreatePropertyComparison<T>(propInfo, isAscending);

            // 转换为列表并排序
            var sortedList = list.ToList();
            sortedList.Sort(comparison);

            return sortedList;
        }

        // 创建属性比较逻辑的方法
        private static Comparison<T> CreatePropertyComparison<T>(PropertyInfo propInfo, bool isAscending)
        {
            return (t1, t2) =>
            {
                var value1 = (IComparable?)propInfo.GetValue(t1, null);
                var value2 = (IComparable?)propInfo.GetValue(t2, null);

                if (value1 == null && value2 == null)
                    return 0; // Both are null, consider them equal
                else if (value1 == null)
                    return isAscending ? -1 : 1; // Null is considered less than non-null
                else if (value2 == null)
                    return isAscending ? 1 : -1; // Non-null is considered greater than null

                // Compare non-null values
                if (isAscending)
                    return value1.CompareTo(value2);
                else
                    return value2.CompareTo(value1);
            };
        }


        public static IPagedList<T> ToPaged<T>(this IEnumerable<T> list, PageParam pager) where T : class, new()
        {
            var res = list.SortListByPropertyName(pager.OrderFileds, pager.OrderBymode == OrderByMode.Asc).Skip((pager.PageIndex - 1) * pager.PageSize).Take(pager.PageSize).ToList();

            return new PagedList<T>()
            {
                PageIndex = pager.PageIndex,
                PageSize = pager.PageSize,
                TotalCount = list.Count(),
                Entities = res
            };
        }

        /// <summary>
        /// 自定义字段分页排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataSource"></param>
        /// <param name="pager"></param>
        /// <returns></returns>
        public static async Task<IPagedList<T>> ToPagedOrderByListAsync<T>(this ISugarQueryable<T> dataSource, PageParam pager) where T : class
        {
            var OrderFileds = "";
            var OrderFileds_CreatedTime = "";
            var type = typeof(T);

            if (!string.IsNullOrWhiteSpace(pager.OrderFileds))
            {
                var property = type.GetProperty(pager.OrderFileds.FirstCharToUpper());

                if (property is not null)
                {
                    var col = property.GetCustomAttribute<SugarColumn>();

                    if (col is not null)
                    {
                        OrderFileds = col.ColumnName;
                    }
                    else
                    {
                        OrderFileds = pager.OrderFileds;
                    }
                }
            }

            var property_time = type.GetProperty(nameof(IAuditable.CreatedTime));
            if (property_time is not null)
            {
                var col = property_time.GetCustomAttribute<SugarColumn>();

                if (col is not null)
                {
                    OrderFileds_CreatedTime = col.ColumnName;
                }
                else
                {
                    OrderFileds_CreatedTime = nameof(IAuditable.CreatedTime);
                }
            }

            var orderByStr = string.IsNullOrEmpty(OrderFileds) ? "" : $"{OrderFileds} {(pager.OrderBymode == OrderByMode.Desc ? OrderByType.Desc : OrderByType.Asc)}";
            var orderByCreateStr = string.IsNullOrEmpty(OrderFileds_CreatedTime) ? "" : $"{OrderFileds_CreatedTime} {(pager.OrderBymode == OrderByMode.Desc ? OrderByType.Desc : OrderByType.Asc)}";

            var totalCount = new RefAsync<int>();
            var page = await dataSource
                .OrderByIF(!string.IsNullOrWhiteSpace(orderByStr), orderByStr)
                .OrderByIF(!string.IsNullOrWhiteSpace(orderByCreateStr), orderByCreateStr)
                .ToPageListAsync(pager.PageIndex, pager.PageSize, totalCount);

            return new PagedList<T>
            {
                PageIndex = pager.PageIndex,
                PageSize = pager.PageSize,
                TotalCount = totalCount.Value,
                Entities = page
            };
        }
    }
}

